/*
 * "can-play" 的class类控制是否可以出牌
 * 在 开 发 者 工 具 中 选 中 一 个 组 件， 该 组 件 会 以 $ vm 的 形 式 暴 露 给 浏 览 器 控 制 台。

 */


new Vue({
	name: 'game',
	el: '#app',
	template: `<div id="#app" :class="cssClass">
			<top-bar :turn="turn" :current-player-index="currentPlayerIndex" :players="players"></top-bar>
			
			<div class="world">
				<castle v-for="(player, index) in players" :key="index" :player="player" :index="index" />
				<div class="land"></div>
				<div class="clouds">
					<cloud v-for="index in 10" :type="(index - 1) % 5 + 1" />
				</div>
			</div>
			
			<transition name="hand">
				<hand v-if="!activeOverlay" :cards="currentHand" @card-play="handlePlayCard" @card-leave-end="handleCardLeaveEnd" />
			</transition>
			
			<transition name="fade">
				<div class="overlay-background" v-if="activeOverlay"></div>
			</transition>
			
			<transition name="zoom">
				<overlay v-if="activeOverlay" :key="activeOverlay" @close="handleOverlayClose">
					<component :is="'overlay-content-' + activeOverlay" :player="currentPlayer" :opponent="currentOpponent" :players="players" />
				</overlay>
			</transition>
		</div>`,
	data: state,
	created() {

	},
	computed: {
		testCard() {
			return cards.curse
		},
		cssClass() {
			return {
				'can-play': this.canPlay,
			}
		}
	},
	mounted() {
		beginGame();
	},
	methods: {
		// 点击卡牌
		// 给自定义组件直接加@click是触发不了，需要增加 .native 修饰符
		handlePlayCard(card) {
			playCard(card);
		},
		// 出牌后续操作
		handleCardLeaveEnd() {
			applyCard();
		},
		// 浮层关闭事件
		handleOverlayClose() {
			overlayCloseHandlers[this.activeOverlay]();
		}
	},
});

// TWEEN.js动画
requestAnimationFrame(animate);

function animate(time) {
	requestAnimationFrame(animate);
	TWEEN.update(time);
}

// 窗口大小变化处理
window.addEventListener('resize', () => {
	state.worldRatio = getWorldRatio();
});

// 玩游戏
state.activeOverlay = 'player-turn';

// 开始游戏
function beginGame() {
	// 分别给各个玩家发牌
	state.players.forEach(drawInitialHand)
}

/*
	param: card
	检查玩家是否可以出牌，然后将此卡牌将手牌中移除，并且调用addCardToPile(在util.js)将卡牌放到弃牌堆中：
*/
function playCard(card) {
	if (state.canPlay) {
		state.canPlay = false;
		// 记录当期打出的卡，方便一会计算卡牌效果
		currentPlayingCard = card;

		// 将卡牌从玩家手中移除
		const index = state.currentPlayer.hand.indexOf(card);
		state.currentPlayer.hand.splice(index, 1);

		// 将卡牌放入弃牌堆
		addCardToPile(state.discardPile, card.id);
	}
}

// 应用当前卡牌的作用
function applyCard() {
	const card = currentPlayingCard;
	applyCardEffect(card);

	// 稍等一会让玩家观察发生了什么
	setTimeout(() => {
		// 检查玩家是否死亡
		state.players.forEach(checkPlayerLost)

		if (isOnePlayerDead()) {
			endGame();
		} else {
			nextTurn();
		}
	}, 700)
}

// 游戏结束,展示结束浮层
function endGame() {
	state.activeOverlay = 'game-over';
}

/*
	nextTurn : 把回合数加一，修改当前玩家，同时显示 player-turn 浮层
*/
function nextTurn() {
	state.turn++;
	state.currentPlayerIndex = state.currentOpponentId;
	state.activeOverlay = 'player-turn';
}

/*
	新的回合开始
*/
function newTurn() {
	state.activeOverlay = null;
	if (state.currentPlayer.skipTurn) {
		skipTurn()
	} else {
		startTurn()
	}
}

// 如果某些卡牌的skipTurn属性为true，那么玩家的回合将会被跳过，对应的还有skippedTurn属性，会在last-play 浮层中向下一名玩家显示对手跳过了上一回合
function skipTurn() {
	state.currentPlayer.skippedTurn = true
	state.currentPlayer.skipTurn = false
	nextTurn()
}

/*
	开始回合
	创 建 startTurn 函 数， 用 于 重 置 玩 家 的 skippedTurn 属 性。 如 果 这 是 玩 家 的 第 二 个 回 合， 则 让 其 抽 一 张 卡 牌（ 这 样 玩 家 在 开 始 新 的 回 合 时， 手 里 总 是 有 5 张 卡 牌）：
*/
function startTurn() {
	state.currentPlayer.skippedTurn = false
	state.currentPlayer.skipTurn = true
	// 如果两名玩家都已经玩过一个回合则抽牌
	if (state.turn > 2) {
		// 抽一张新的卡牌
		setTimeout(() => {
			state.currentPlayer.hand.push(drawCard())
			state.canPlay = true
		}, 800)
	} else {
		state.canPlay = true
	}
}

// 浮层界面的关闭动作
// 可以将每个浮层的触犯动作,放到一个映射里面,键是浮层的类型,值则是操作出发时调用的函数
var overlayCloseHandlers = {
	'player-turn'() {
		// 如果回合数大于1，则展示上一回合play的浮层，否则开启新回合
		if (state.turn > 1) {
			state.activeOverlay = 'last-play';
		} else {
			newTurn();
		}
	},
	'last-play'() {
		newTurn()
	},
	'game-over'() {
		// 重新加载游戏
		document.location.reload()
	}
}
